package com.mintuo.litecomposite.common.util;

import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;

public class SignUtil {
    /**
     * 计算签名
     * @param map 待计算报文实体map
     * @param signKey signKey
     * @return 结果签名值
     */
    public static String getSign(Map<String, String> map, String signKey) {
        String str = sortAcsWithoutBlank(map, signKey);
        byte[] resultArr = hash(str.getBytes(StandardCharsets.UTF_8));
        return ByteUtils.toHexString(resultArr);
    }

    private static String sortAcsWithoutBlank(Map<String, String> map, String signKey) {
        /*
         * 入参数按key值进行升序排列后，将不为空的参数按照key=value的形式进行连接
         * 再结尾拼接接固定秘钥串，最后使用md5算法计算摘要
         * 固定加密串由源广信提供
         */
        TreeMap<String, String> treeMap = new TreeMap<>(map);

        StringBuilder stringBuilder  = new StringBuilder();
        treeMap.forEach((key, value) -> {
            if (!StringUtils.isEmpty(value)) {
                stringBuilder.append(key).append("=").append(value);
            }
        });
        return stringBuilder.append(signKey).toString();
    }



    public static byte[] hash(byte[] srcData) {
        SM3Digest digest = new SM3Digest();
        digest.update(srcData, 0, srcData.length);
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return hash;
    }

    /**
     * 验证签名是否正确
     * @param signature 待验证签名
     * @param signKey 签名密钥
     * @param map 待验证请求实体map
     * @return 是否正确 true:正确; false:错误
     */
    public static boolean verify(String signature, String signKey, Map<String, String> map) {
        String actuallySign = getSign(map, signKey);
        return actuallySign.equals(signature);
    }
}
